package com.tcsa.openplatform;

import com.alibaba.fastjson.JSONObject;
import com.tcsa.openplatform.enums.SignEnum;
import com.tcsa.openplatform.util.AESUtil;
import com.tcsa.openplatform.util.RSASignUtil;
import com.tcsa.openplatform.util.RsaKey;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.UUID;

/**
 * @Package: com.tcsa.openplatform.sdk.encrypt
 * @Author: Shane
 * @Mail: shanbaohua@tcsa.cloud
 * @CreateTime: 2021-03-12 11:38
 * @Description: 加解密和签名、验签demo
 */
public class CryptAndSignDemo {

    public static void main(String[] args) throws Exception {
        // 真实请求数据
        String requestData = "Demo request data";
        // 分配的appId
        String appId = "king";
        // 分配的app密钥
        String appSecret = "NYWnrK&*z!CX";
        // 真实请求数据加密
        String encryptData = AESUtil.encrypt2Str(requestData, appSecret);
        // / 真实请求数据组装
        JSONObject jsonForSign = new JSONObject();
        jsonForSign.put("data", encryptData);
        System.out.println("demo request body: " + encryptData);

        // 参与签名的字段
        String method = HttpMethod.POST.name().toLowerCase();
        Long timestamp = System.currentTimeMillis();
        String nonce = UUID.randomUUID().toString().replaceAll("-", "");

        // 拼接参与签名的字段
        // 这里要注意一下字段的顺序，如无法保证可以分割后借助TreeMap排序
        StringBuilder paramStr = new StringBuilder("appId=").append(appId).append("&nonce=")
                .append(nonce).append("&st=").append(SignEnum.rsa).append("&timestamp=").append(timestamp);

        // 生成RSA对
        RsaKey rsaKey = RSASignUtil.generate();

        // 请求地址uri
        String uri = "http://localhost:8080/api/acquirer/stock/capital";

        // 拼接签名体
        StringBuilder signStr = new StringBuilder(method).append("\n")
                .append(uri).append("\n").append(paramStr).append("\n").append(jsonForSign.toJSONString());
        System.out.println();
        System.out.println("******************************* wait for sign str *******************************");
        System.out.println(signStr);
        System.out.println("******************************* wait for sign str *******************************");
        System.out.println();

        // 生成签名
        String sign = RSASignUtil.sign(signStr.toString(), rsaKey.getPrivateKey());
        System.out.println("sign: " + sign);

        // 验证签名
        boolean result = RSASignUtil.verify(signStr.toString(), sign, rsaKey.getPublicKey());
        System.out.println("sign verify result: " + result);

        // 模拟发起一个真实请求
        // 真实请求示例：http://localhost:8080/api/acquirer/stock/capital?appId={appId}&nonce={nonce}&st=rsa&timestamp={timestamp}
        /**
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("sign", sign);
        HttpEntity<String> entity = new HttpEntity(jsonForSign.toJSONString(), headers);
        URI mockURI = new URI(uri.concat("?").concat(paramStr.toString()));
        ResponseEntity<String> response = new RestTemplate().postForEntity(mockURI, entity, String.class);
        */
    }

}
